from django.contrib.auth.backends import ModelBackend
import re
from django.conf import settings
from .models import User
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData
from . import constants

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr


def send_email(to_email,verify_url):
    my_sender = settings.EMAIL_HOST  # 发件人邮箱账号
    my_pass = settings.EMAIL_HOST_PASSWORD  # 发件人邮箱密码
    my_user = to_email  # 收件人邮箱账号，我这边发送给自己

    html_message = '<p>尊敬的用户您好！</p>' \
                    '<p>感谢您使用美多商城。</p>' \
                    '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                    '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
    ret = True
    try:
        msg = MIMEText(html_message, 'html', 'utf-8')
        msg['From'] = formataddr(["FromRunoob", my_sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To'] = formataddr(["FK", my_user])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject'] = "菜鸟教程发送邮件测试"  # 邮件的主题，也可以说是标题

        server = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发件人邮箱中的SMTP服务器，端口是25
        server.login(my_sender, my_pass)  # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender, [my_user, ], msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 关闭连接
    except Exception:  # 如果 try 中的语句没有执行，则会执行下面的 ret=False
        return None
    return ret


def check_verify_email_token(token):
    """
    反序列化token,获取到user
    :param token: 序列化后的用户信息
    :return: user
    """
    s = Serializer(settings.SECRET_KEY, constants.VERIFY_EMAIL_TOKEN_EXPIRES)
    try:
        data = s.loads(token)
    except BadData:
        return None
    else:
        # 从data中取出user_id和email
        user_id = data.get('user_id')
        email = data.get('email')
        try:
            user = User.objects.get(id=user_id, email=email)
        except User.DoesNotExist:
            return None
        else:
            return user


def generate_verify_email_url(user):
    """
    把邮箱链接进行序列化
    :param user: 当前登录的用户
    :return: verify_url
    """
    serializer = Serializer(settings.SECRET_KEY,expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)

    data ={'user_id': user.id, 'email': user.email}
    token=serializer.dumps(data).decode()
    verify_url=settings.EMAIL_VERIFY_URL +'?token=' + token
    return verify_url

def get_user_by_account(account):
    """
    根据account查询用户
    :param account: 用户名或手机号
    :return: user
    """
    try:
        if re.match('^1[3-9]\d{9}$', account):
            # 手机号登录
            user = User.objects.get(mobile=account)
        else:
            # 用户名登录
            user = User.objects.get(username=account)
    except User.DoesNotExist:
        return None
    else:
        return user

class UsernameMobileAuthBackend(ModelBackend):
    """自定义用户认证后端"""

    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        重写认证方法，实现多账号登录
        :param request: 请求对象
        :param username: 用户名
        :param password: 密码
        :param kwargs: 其他参数
        :return:  user
        """
        # 根据传入的username获取user对象，username是用户名或手机号
        user = get_user_by_account(username)
        if user and user.check_password(password):
            return user